﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.IO;
using System.Xml.Linq;

namespace Numero3DBObject
{
    public partial class Form1 : Form
    {
        private ConnexionDB connexion;
        private List<Etudiant> listeEtudiant;
        private List<Cours> listeCours;
        private List<Resultat> listeResultat;

        private const string CHEMIN_ETUDIANT = @"Etudiants.xml";
        private const string CHEMIN_COURS = @"Cours.xml";
        private const string CHEMIN_RESULTAT = @"Resultats.xml";

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            connexion = ConnexionDB.Creer();

            listeCours = connexion.ExecuterAdapterCours("SELECT * FROM cours");


            var lItem = listeCours.Select(co =>
            {
                ListViewItem item = new ListViewItem(co.Sigle);
                item.SubItems.Add(co.Nom);
                item.SubItems.Add(co.Description);
                item.SubItems.Add(co.Credit.ToString());
                return item;
            });
            listView1.Items.AddRange(lItem.ToArray());


            listeResultat = connexion.ExecuterAdapterResultat("SELECT * FROM resultats");


            lItem = listeResultat.Select(res =>
            {
                ListViewItem item = new ListViewItem(res.Matricule);
                item.SubItems.Add(res.Sigle);
                item.SubItems.Add(res.Cote);
                return item;
            });
            listView2.Items.AddRange(lItem.ToArray());


            listeEtudiant = connexion.ExecuterAdapterEtudiant("SELECT * FROM etudiants");
            
       
            lItem = listeEtudiant.Select(etu =>
                {
                    ListViewItem item = new ListViewItem(etu.Matricule);
                    item.SubItems.Add(etu.Nom);
                    item.SubItems.Add(etu.Prenom);
                    item.SubItems.Add(etu.Adresse);
                    item.SubItems.Add(etu.Ville);
                    item.SubItems.Add(etu.Code);
                    item.SubItems.Add(etu.Tel);
                    item.SubItems.Add(etu.Departement.ToString());
                    return item;
                });
            listView3.Items.AddRange(lItem.ToArray());

            XMLSerialize(typeof(List<Cours>), listeCours.AsEnumerable<object>(), CHEMIN_COURS);
            XMLSerialize(typeof(List<Resultat>), listeResultat.AsEnumerable<object>(), CHEMIN_RESULTAT);
            XMLSerialize(typeof(List<Etudiant>), listeEtudiant.AsEnumerable<object>(), CHEMIN_ETUDIANT);


            List<Cours> deserializedListeCours = XMLDeserialize<Cours>(CHEMIN_COURS);
            List<Resultat> deserializedListeResultat = XMLDeserialize<Resultat>(CHEMIN_RESULTAT);
            List<Etudiant> deserializedListeEtudiant = XMLDeserialize<Etudiant>(CHEMIN_ETUDIANT);

          
            for(int i = 0; i < deserializedListeCours.Count; i++)
            {
                if (listeCours.ElementAt(i) != deserializedListeCours.ElementAt(i))
                    MessageBox.Show("Élément original Cours " + i.ToString() + " différent de l'élément 'désérializé'!", "Alerte!");
            }

            for (int i = 0; i < deserializedListeResultat.Count; i++)
            {
                if (listeResultat.ElementAt(i) != deserializedListeResultat.ElementAt(i))
                    MessageBox.Show("Élément original Resultat " + i.ToString() + " différent de l'élément 'désérializé'!", "Alerte!");
            }

            for (int i = 0; i < deserializedListeEtudiant.Count; i++)
            {
                if (listeEtudiant.ElementAt(i) != deserializedListeEtudiant.ElementAt(i))
                    MessageBox.Show("Élément original Étudiant " + i.ToString() + " différent de l'élément 'désérializé'!", "Alerte!");
            }

            XElement xmlCours = XElement.Load(CHEMIN_COURS);
            XElement xmlResultat = XElement.Load(CHEMIN_RESULTAT);
            XElement xmlEtudiant = XElement.Load(CHEMIN_ETUDIANT);


            var listeCourParEtudiant = from etudiant in xmlEtudiant.Elements("Etudiant").Distinct()
                               join resultat in xmlResultat.Elements("Resultat").Distinct() on etudiant.Element("Matricule").Value equals resultat.Element("Matricule").Value
                               join cours in xmlCours.Elements("Cours").Distinct() on resultat.Element("Sigle").Value equals cours.Element("Sigle").Value
                               select new { Prenom = etudiant.Element("Prenom").Value, Nom = etudiant.Element("Nom").Value, Sigle = cours.Element("Sigle").Value , NomCours = cours.Element("Nom").Value };


            lItem = listeCourParEtudiant.Select(etu =>
            {
                ListViewItem item = new ListViewItem(etu.Nom);
                item.SubItems.Add(etu.Prenom);
                item.SubItems.Add(etu.Sigle);
                item.SubItems.Add(etu.NomCours);
                return item;
            });
            listView4.Items.AddRange(lItem.ToArray());

        }


        private void XMLSerialize(Type type, IEnumerable<object> listeobjet, string chemin)
        {
            XmlSerializer SerializerObj = new XmlSerializer(type);
 
            TextWriter WriteFileStream = new StreamWriter(chemin);

            try
            {
                SerializerObj.Serialize(WriteFileStream, listeobjet);
            }
            catch (IOException e)
            {

                MessageBox.Show("Erreur desérialize;" + e.Message);
            }
 
            WriteFileStream.Close();      
        }

        private List<T> XMLDeserialize<T>(string chemin)
        {
            List<T> listeobjet = null;

            FileStream ReadFileStream = new FileStream(chemin, FileMode.Open, FileAccess.Read, FileShare.Read);

            XmlSerializer SerializerObj = new XmlSerializer(typeof(List<T>));

            try
            {
                listeobjet = (List<T>)SerializerObj.Deserialize(ReadFileStream);
            }
            catch (IOException e)
            {

                MessageBox.Show("Erreur desérialize;" + e.Message);
            }
            

            ReadFileStream.Close();

            return listeobjet;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            ConnexionDB.Detruire();
        }
    }
}
